package de.fhhannover.inform.wari.grp8.spiel;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
import java.util.Vector;

import de.fhhannover.inform.wari.strategy.MoveStrategy;
/**
 * @author Shanmugaesan
 * 
 */
public class StrategyHandler {
	private static StrategyHandler strategyHanlder;
	// Strategy-name -> Strategy-class-path
	private HashMap<String, String> strategyTable;
    private HashMap<String, String> grpNameIDTable; 
	private StrategyHandler() {
		Collection<String> fileCollection = getClasses(new File("bin"));
		String[] files = new String[fileCollection.size()];
		files = fileCollection.toArray(files);
		strategyTable = new HashMap<String,String>();
		grpNameIDTable = new HashMap<String,String>();
		for (String fileName : files) {
			Class<?> c = getClass(fileName);
			Class<?>[] interfaces = c.getInterfaces();
			boolean isStrategy = false;
			for (Class<?> i : interfaces) {
				if (i.getName() == "de.fhhannover.inform.wari.strategy.MoveStrategy") {
					isStrategy = true;
					break;
				}
			}
			if (isStrategy) {
				MoveStrategy strategy = null;
				try {
					strategy = (MoveStrategy) c.newInstance();
				} catch (InstantiationException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				strategyTable.put(strategy.getStrategyName(),fileName); //
				grpNameIDTable.put(strategy.getGroupID(),strategy.getStrategyName());
			}
		}
	}
	
	private Collection<String> getClasses(File dir) {
	    
	    File[] directory_entries = dir.listFiles();
	    Vector<String> files = new Vector<String>();
	    for (File file : directory_entries) {
	        if (file.getName().endsWith(".class")) {
	            files.add(file.toString());
	        }
	        if (file.isDirectory()) {
	            files.addAll(getClasses(file));
	        }
	    }
        return files;
	}

	public static StrategyHandler getStrategyHandler() {
		if (strategyHanlder == null) {
			strategyHanlder = new StrategyHandler();
		}
		return strategyHanlder;
	}

	private Class<?> getClass(String fileName) {
		Class<?> loadedStrategy = null;
		try {
			int countWithoutFiletype = fileName.length() - ".class".length();
			String className = fileName.substring(4, countWithoutFiletype).replace('\\', '.').replace('/', '.');
			loadedStrategy = Class.forName(className);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return loadedStrategy;
	}

	public Set<String> getStrategyNames() {
		return strategyTable.keySet();
	}
	
	public Set<String> getStrategyIDs(){
		return this.grpNameIDTable.keySet();
	}
	
    public HashMap<String, String> getIDandNameMap(){
    	return this.grpNameIDTable;
    }
    public HashMap<String, String> getNamesMap(){
    	return this.strategyTable;
    }
	public Object getStrategyByName(String name) {
		try {
			return getClass(strategyTable.get(name)).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

}
